/*
 * @(#)ProjectSpeReqManager.java
 * 2014-4-24 上午09:21:17
 * 
 *
 * Copyright (c) 2018-2028, HangZhou QiYun InfoTech Co.,Ltd. .
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.qyxx.platform.gsmng.common.service;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.apache.commons.lang.math.NumberUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.qyxx.platform.sysmng.accountmng.entity.User;


/**
 *  项目定制化需求服务类
 *  @author gxj
 *  @version 1.0 2014-4-24 上午09:21:17
 *  @since jdk1.6 
 */
@Service
@Scope("prototype")
@Transactional
public class ProjectSpeReqManager {
	
	private static final Logger logger = LoggerFactory.getLogger(ProjectSpeReqManager.class);
	
	private GsMngManager gsMngManager;
	
	private GsMngManager gmm;
	
	private User user;
	
	private String entityName;
	
	private ExecutorService executor = Executors.newFixedThreadPool(5);
	
	/**
	 * @param gsMngManager
	 */
	@Autowired
	public void setGsMngManager(GsMngManager gsMngManager) {
		this.gsMngManager = gsMngManager;
	}
	
	/**
	 * @param gsMngManager
	 */
	@Autowired
	public void setGmm(GsMngManager gsMngManager) {
		this.gmm = gsMngManager;
	}
	
	/**
	 * @param user
	 */
	public void setUser(User user) {
		this.user = user;
		this.gsMngManager.setUser(user);
	}
	
	/**
	 * @param entityName
	 */
	public void setEntityName(String entityName) {
		this.entityName = entityName;
		this.gsMngManager.setEntityName(entityName);
	}




	/**
	 * 科百特项目生成产品方法
	 * 
	 * @return
	 * @throws Exception
	 */
	@SuppressWarnings({ "unchecked", "rawtypes" })
	public String genProductForCbt(Map<String, Object> map) {
		Map<String, Object> xhObj = (Map<String, Object>)map.get("xhObj"); //型号对象
		List wdList = (List)map.get("weiduList"); //维度对象列表
		Map<String, Object> param = (Map<String, Object>)map.get("param");
		String subTableKey = (String)param.get("subTableKey");
		String uniqueAttr = (String)param.get("uniqueAttr");
		Boolean isUpdate = (Boolean)param.get("isUpdate");
		Integer batchSize = NumberUtils.toInt((String)param.get("batchSize"), 500); //批次数量，默认500
		List crossList = cross(wdList);
		Long count = 1L;
		//Transaction ts = gsMngManager.beginTransaction();//开启事务
		Integer len = crossList.size();
		logger.info("生成记录数：" + len);
		
		gmm.setEntityName("chanpinxuanxing.ChanPinXuanXingZhuBiao");//产品类型
		gmm.setUser(user);
		String sid = String.valueOf(xhObj.get("chanpinleixing")); //获取产品类型ID
		Long id = Long.valueOf(sid);
		gmm.updateColumn(id, "chanpinshengchengkaishishijian", new Date());//产品生成开始时间
		gmm.updateColumn(id, "chanpinshengchengzhuangtai", len + "条产品数据正在生成中...");//产品生成状态
		gmm.updateColumn(id, "chanpinshengchengjieshushijian", null);//产品生成结束时间
		gmm.flushData();//更新产品生成信息
		
		for(Object obj : crossList) {
			Map<String, Object> result = new HashMap<String, Object>();
			gsMngManager.copyMap(result, xhObj); //复制型号对象
			Map<String, Object> weiduMap = new HashMap<String, Object>(); //产品维度属性
			StringBuffer chanpinguige = new StringBuffer(""); //产品规格
			List<Object> res = (List<Object>)obj;
			for(Object wdObj : res) { //组合多个维度
				Map<String,Object> wd = (Map<String, Object>)wdObj;
				String attrKey = (String)wd.get("attrKey");
				String attrCaption = (String)wd.get("attrCaption");
				String valKey = (String)wd.get("valKey");
				String valCaption = (String)wd.get("valCaption");
				weiduMap.put(attrKey, valKey); // 用于产品属性
				result.put(attrKey, valKey); // 用于生成编码规则
				String vc = StringUtils.replace(valCaption, "空", ""); // 替换空字符
				result.put(attrKey+"_caption", vc); // 用于生成编码规则
				//weiduMap.put(attrKey + "_attrCaption", attrCaption);
				//weiduMap.put(attrKey + "_valCaption", valCaption);
				chanpinguige.append(attrCaption); // 生成产品规格
				chanpinguige.append("：");
				chanpinguige.append(vc); 
				chanpinguige.append(";");
			}
			List<Map<String, Object>> updateList = new ArrayList<Map<String, Object>>();
			updateList.add(weiduMap);
			Map<String, List> updateMap = new HashMap<String, List>();
			updateMap.put("updated", updateList);
			
			result.put(subTableKey, updateMap); // 扩展属性表
			result.put("chanpinguige", chanpinguige.toString()); //产品规格
			result.put("gongchanghuohaoguige", chanpinguige.toString()); //工厂货号规格
			String cpbm = genBianMaByGuiZe((String)result.get("bianmaguize"),result); //产品编码规则
			result.put("chanpinbianma", cpbm); //产品编码
			String gchh = genBianMaByGuiZe((String)result.get("gongchanghuohaoguize"),result); //工厂货号
			result.put("gongchanghuohao", gchh); //产品工厂货号
			String cpmc = result.get("caption") + "-" + cpbm; //产品名称 = 产品类型 + 产品编码
			result.put("chanpinmingchen", cpmc); //产品名称
			String gynr = genBianMaByGuiZe((String)result.get("gangyinnarongguize"),result); //钢印内容
			result.put("gangyinnarongguize", gynr);//钢印内容
			
			gsMngManager.saveEntityByIdAttr(result, uniqueAttr, isUpdate); // 保存生成的产品信息
			if(count%batchSize == 0) { // 每隔batchSize条数据，提交1次
				gsMngManager.flushData();
				//ts.commit();
				//ts = gsMngManager.beginTransaction();
				//System.out.println("提交记录数：" + count);
			}
			logger.info("处理记录数：" + count);
			count++;
		}
		gsMngManager.flushData();
		//ts.commit();
		//gsMngManager.beginTransaction();//开启事务
		
		gmm.updateColumn(id, "chanpinshengchengzhuangtai", len + "条产品数据已生成完毕");//产品生成状态
		gmm.updateColumn(id, "chanpinshengchengjieshushijian", new Date());//产品生成结束时间
		
		return null;
	}
	
	/**
	 * 根据编码规则生成编码
	 * 
	 * @param guize
	 * @param result
	 * @return
	 */
	public static String genBianMaByGuiZe(String guize, Map<String, Object> result) {
		if(StringUtils.isNotBlank(guize)) {
			Pattern p = Pattern.compile("([^\\[]+?)(?=\\])"); 
			Matcher m = p.matcher(guize);
			String bm = guize;
			while(m.find()) {
				String attr = m.group();
				bm = StringUtils.replace(bm, "[" + attr + "]", (String)result.get(attr)); // 替换维度属性
			}
			bm = StringUtils.replace(bm, "空", ""); // 替换空值
			return bm;
		} else {
			return "";
		}
	}
	
	@SuppressWarnings({ "rawtypes", "unchecked" })
	public List cross(List inputList) {
		List mainList = (List) inputList.get(0);
        for (int i = 1; i < inputList.size(); i++) {
            List addList = (List) inputList.get(i);
            List temp = new ArrayList();
            for (int j = 0; j < mainList.size(); j++) //每次先计算两个集合的笛卡尔积，然后用其结果再与下一个计算   
            {
                for (int k = 0; k < addList.size(); k++) {
                    List cut = new ArrayList();
                    if (mainList.get(j) instanceof ArrayList) {
                        cut.addAll((ArrayList) mainList.get(j));
                    } else {
                        cut.add(mainList.get(j));
                    }
                    if (addList.get(k) instanceof ArrayList) {
                        cut.addAll((ArrayList) addList.get(k));
                    } else {
                        cut.add(addList.get(k));
                    }
                    temp.add(cut);
                }
            }
            mainList = temp;
        }
        return mainList;
	}
	
	/**
	 * 静默生成产品信息
	 * 
	 * @param map
	 * @return
	 */
	public String genProductForCbtSilent(Map<String, Object> map) {
		executor.execute(new ThreadPoolTask(map));
		return null;
	}
	
	/**
	 *  批量生成任务，后台执行
	 *  
	 *  @author gxj
	 *  @version 1.0 2014-5-4 下午06:27:28
	 *  @since jdk1.6
	 */
	private class ThreadPoolTask implements Runnable, Serializable {
		/**
		 * long
		 */
		private static final long serialVersionUID = 7814355394771090477L;

		private Map<String, Object> paramMap;
		
		public ThreadPoolTask(Map<String, Object> paramMap) {
			this.paramMap = paramMap;
		}
		
		@Override
		public void run() {
			try {
				genProductForCbt(paramMap);
			} catch(Exception e) {
				logger.error("批量生成产品信息出错", e);
			}
		}
		
	}

	/**
	 * 
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("xinhao", "app");
		map.put("weidu1", "1空");
		System.out.println(genBianMaByGuiZe("[xinhao][weidu1]", map));
	}

}
